package com.triones.yjj.service.impl;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.config.YjjExternalAuthConfig;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtil;
import com.ruoyi.common.utils.SnCreator;
import com.ruoyi.system.mapper.SysUserMapper;
import com.triones.yjj.entity.*;
import com.triones.yjj.entity.vo.PaymentBillVO;
import com.triones.yjj.mapper.*;
import com.triones.yjj.service.WxPayService;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.*;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.wechat.pay.java.core.http.Constant.*;

/**
 * 微信支付
 *
 * @Author: triones
 */
@Service
@RequiredArgsConstructor
public class WxPayServiceImpl implements WxPayService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    private final YjjExternalAuthConfig yjjExternalAuthConfig;

    private final OrderMapper orderMapper;

    private final PaymentBillMapper paymentBillMapper;

    private final RefundTradeMapper refundTradeMapper;

    private final MemberMapper memberMapper;

    private final ShareMapper shareMapper;

    private final OrderTradeRecordMapper orderTradeRecordMapper;

    private final MemberGroupPurchaseMapper memberGroupPurchaseMapper;

    private final MemberGroupPurchaseItemMapper memberGroupPurchaseItemMapper;

    private final GroupPurchaseGoodsItemMapper groupPurchaseGoodsItemMapper;

    private final SysUserMapper sysUserMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean refund(Long orderId) {
        synchronized (this) {
            /**
             * 获取订单信息
             */
            OrderDO order = orderMapper.selectById(orderId);
            if (order == null) {
                throw new ServiceException("无订单信息");
            }
            /**
             * 获取订单支付信息
             */
            LambdaQueryWrapper<PaymentBillDO> paymentBillWrapper = Wrappers.lambdaQuery(PaymentBillDO.class);
            paymentBillWrapper.eq(PaymentBillDO::getOrderNo,order.getOrderNo()).eq(PaymentBillDO::getIsPay,1);
            PaymentBillVO paymentBillVO = paymentBillMapper.selectVoOne(paymentBillWrapper);
            String refundSn = SnCreator.getRefundSn();
            RefundTradeDO refundTradeDO = new RefundTradeDO();
            if (paymentBillVO == null) {
                throw new ServiceException("没有查询到订单支付信息");
            }

            /**
             * 查询金额是否足够
             */
            SysUser sysUser = sysUserMapper.selectVoById(order.getUserId());
            if (sysUser == null) {
                throw new ServiceException("未查询到商家信息");
            }
            //待核销状态只需要关注是否产生分销金额
            if (order.getStatus() == 2) {
                BigDecimal distributionAmount = order.getOneDistributionAmount().add(order.getTwoDistributionAmount());
                BigDecimal waitSettlementAmount = Convert.toBigDecimal(sysUser.getWaitSettlementAmount(),BigDecimal.ZERO);
                BigDecimal walletAmount = Convert.toBigDecimal(sysUser.getWalletAmount(),BigDecimal.ZERO);
                //订单待核销钱还未分账（只需要关注钱够不够结算分销金额即可）
                if (distributionAmount.compareTo(BigDecimal.ZERO) == 1) {
                    //表示该订单产生分销金额
                    if (waitSettlementAmount.compareTo(distributionAmount) == -1) {
                        //表示待清算金额小于分销总金额
                        if (walletAmount.compareTo(distributionAmount) == -1) {
                            //表示可提现金额小于分销总金额
                            if (waitSettlementAmount.add(walletAmount).compareTo(distributionAmount) == -1) {
                                //表示 待清算金额 + 可提现金额小于分销总金额
                                throw new ServiceException("余额不足，请充值后再进行退款");
                            } else {
                                //先扣除待请算金额的钱，差的从可提现金额里面扣
                                sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                                BigDecimal difference = distributionAmount.subtract(waitSettlementAmount);
                                sysUser.setWalletAmount(walletAmount.subtract(difference));
                            }
                        } else {
                            //先扣除待请算金额的钱，差的从可提现金额里面扣
                            sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                            BigDecimal difference = distributionAmount.subtract(waitSettlementAmount);
                            sysUser.setWalletAmount(walletAmount.subtract(difference));
                        }
                    } else {
                        //超出的金额从待清算金额里面扣
                        sysUser.setWaitSettlementAmount(waitSettlementAmount.subtract(distributionAmount));
                    }
                }
            } else {
                //订单已核销（已结算至待清算金额）
                BigDecimal settlementAmountAmount = order.getOneDistributionAmount().add(order.getTwoDistributionAmount()).add(order.getActualAmount());
                BigDecimal waitSettlementAmount = Convert.toBigDecimal(sysUser.getWaitSettlementAmount(),BigDecimal.ZERO);
                BigDecimal walletAmount = Convert.toBigDecimal(sysUser.getWalletAmount(),BigDecimal.ZERO);
                //订单待核销钱还未分账（只需要关注钱够不够结算分销金额即可）
                if (settlementAmountAmount.compareTo(BigDecimal.ZERO) == 1) {
                    if (waitSettlementAmount.compareTo(settlementAmountAmount) == -1) {
                        if (walletAmount.compareTo(settlementAmountAmount) == -1) {
                            if (waitSettlementAmount.add(walletAmount).compareTo(settlementAmountAmount) == -1) {
                                //表示 待清算金额 + 可提现金额小于分销总金额
                                throw new ServiceException("余额不足，请充值后再进行退款");
                            } else {
                                //先扣除待请算金额的钱，差的从可提现金额里面扣
                                sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                                BigDecimal difference = settlementAmountAmount.subtract(waitSettlementAmount);
                                sysUser.setWalletAmount(walletAmount.subtract(difference));
                            }
                        } else {
                            //先扣除待请算金额的钱，差的从可提现金额里面扣
                            sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                            BigDecimal difference = settlementAmountAmount.subtract(waitSettlementAmount);
                            sysUser.setWalletAmount(walletAmount.subtract(difference));
                        }
                    } else {
                        //超出的金额从待清算金额里面扣
                        sysUser.setWaitSettlementAmount(waitSettlementAmount.subtract(settlementAmountAmount));
                    }
                }
            }
            try {
                // 使用自动更新平台证书的RSA配置
                // 一个商户号只能初始化一个配置，否则会因为重复的下载任务报错
                Config config =
                    new RSAAutoCertificateConfig.Builder()
                        .merchantId(yjjExternalAuthConfig.getMchid())
                        //使用 SDK 不需要计算请求签名和验证应答签名
                        // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
                        .privateKeyFromPath(yjjExternalAuthConfig.getKeyPath())
                        .merchantSerialNumber(yjjExternalAuthConfig.getMchSerialNo())
                        .apiV3Key(yjjExternalAuthConfig.getKey())
                        .build();
                // 构建退款service
                RefundService service = new RefundService.Builder().config(config).build();
                //构建退款请求
                CreateRequest request = new CreateRequest();
                //构建订单金额信息
                AmountReq amountReq = new AmountReq();
                //退款金额
                Integer getRealityPayAmount = Convert.toInt(order.getRealityPayAmount().multiply(Convert.toBigDecimal(100)));
//                测试使用
//                Integer getRealityPayAmount = 1;
                amountReq.setRefund(Convert.toLong(getRealityPayAmount));
                //原订单金额
                amountReq.setTotal(Convert.toLong(getRealityPayAmount));
                //货币类型(默认人民币)
                amountReq.setCurrency("CNY");
                request.setAmount(amountReq);
                request.setOutTradeNo(paymentBillVO.getOrderNo());
                request.setReason("退款");
                //商户退款单号
                request.setOutRefundNo(refundSn);
                request.setNotifyUrl(yjjExternalAuthConfig.getRefundNotifyUrl());
                // 调用微信sdk退款接口
                Refund refund = service.create(request);
                //接收退款返回参数
                  Status status = refund.getStatus();
                logger.info("请求退款返回status：" + status);
                if (Status.SUCCESS.equals(status)) {
                    logger.info("退款成功 ---> status：" + status);
                    return true;
                }
                if (Status.PROCESSING.equals(status)) {
                    logger.info("退款中 ---> status：" + status);

                    /**
                     * 更新商家信息
                     */
                    sysUserMapper.updateById(sysUser);

                    /**
                     * 更新拼团表数据
                     */
                    MemberGroupPurchaseItemDO newLeader = null;
                    MemberGroupPurchaseItemDO memberGroupPurchaseItemDO = memberGroupPurchaseItemMapper.selectById(order.getGroupPurchaseItemId());
                    if (memberGroupPurchaseItemDO == null) {
                        throw new ServiceException("拼团不存在");
                    }
                    MemberGroupPurchaseDO memberGroupPurchaseDO = memberGroupPurchaseMapper.selectById(order.getGroupPurchaseId());
                    if (memberGroupPurchaseDO == null) {
                        throw new ServiceException("拼团不存在");
                    }
                    /**
                     * 查看具有相同拼团id的订单
                     */
                    List<OrderDO> orderDOS = orderMapper.selectList(
                        new LambdaQueryWrapper<OrderDO>()
                            .eq(OrderDO::getGroupPurchaseId,memberGroupPurchaseDO.getId()).in(OrderDO::getStatus,1,2,5));

                    /**
                     * 作废当前子拼团信息
                     */
                    memberGroupPurchaseItemDO.setIsNullify(1);
                    memberGroupPurchaseItemMapper.updateById(memberGroupPurchaseItemDO);
                    /**
                     * 如果退款的是团长，选这一个新的团长
                     */
                    LambdaQueryWrapper<MemberGroupPurchaseItemDO> wrapper = Wrappers.lambdaQuery(MemberGroupPurchaseItemDO.class);
                    wrapper.eq(MemberGroupPurchaseItemDO::getGroupPurchaseId,order.getGroupPurchaseId())
                        .eq(MemberGroupPurchaseItemDO::getIsNullify,0)
                        .ne(MemberGroupPurchaseItemDO::getId,memberGroupPurchaseItemDO.getId())
                        .orderByAsc(MemberGroupPurchaseItemDO::getCreateTime);
                    List<MemberGroupPurchaseItemDO> purchaseItemDOS = memberGroupPurchaseItemMapper.selectList(wrapper);
                    if (memberGroupPurchaseItemDO.getIdentity() == 1) {
                        if (purchaseItemDOS != null && purchaseItemDOS.size() > 0) {
                            newLeader = purchaseItemDOS.get(0);
                            newLeader.setIdentity(1);
                            memberGroupPurchaseItemMapper.updateById(newLeader);
                        }
                        /**
                         * 作废该主团
                         */
                        memberGroupPurchaseDO.setStatus(-1);
                    }

                    /**
                     * 更新拼团主表数据
                     */
                    Integer updatePersonnelNumber = memberGroupPurchaseDO.getPersonnelNumber() - 1;

                    //更新当前拼团信息
                    LambdaQueryWrapper<GroupPurchaseGoodsItemDO> groupPurchaseGoodsItemWrapper = Wrappers.lambdaQuery(GroupPurchaseGoodsItemDO.class);
                    groupPurchaseGoodsItemWrapper.eq(GroupPurchaseGoodsItemDO::getGroupPurchaseGoodsId,order.getGroupPurchaseGoodsId())
                        .orderByAsc(GroupPurchaseGoodsItemDO::getConstituteNumber);
                    List<GroupPurchaseGoodsItemDO> goodsItemDOS = groupPurchaseGoodsItemMapper.selectList(groupPurchaseGoodsItemWrapper);
                    //当前拼团商品阶梯id
                    Long groupPurchaseGoodsItemId = 0L;
                    Integer maxPersonnelNumber = 0;
                    //当前拼团下一个商品阶梯id
                    Long nextGroupPurchaseGoodsItemId = 0L;
                    Integer groupPurchaseStatus = -1;
                    if (updatePersonnelNumber > 0) {
                        if (goodsItemDOS != null && goodsItemDOS.size() > 0) {
                            for (GroupPurchaseGoodsItemDO goodsItemDO : goodsItemDOS) {
                                if (updatePersonnelNumber >= goodsItemDO.getConstituteNumber()) {
                                    groupPurchaseGoodsItemId = goodsItemDO.getId();
                                    maxPersonnelNumber = goodsItemDO.getConstituteNumber();
                                    nextGroupPurchaseGoodsItemId = goodsItemDO.getId();
                                } else {
                                    nextGroupPurchaseGoodsItemId = goodsItemDO.getId();
                                    break;
                                }
                            }
                        }
                        if (groupPurchaseGoodsItemId == 0) {
                            groupPurchaseStatus = 1;
                        } else if (groupPurchaseGoodsItemId != 0 && (!groupPurchaseGoodsItemId.equals(nextGroupPurchaseGoodsItemId))) {
                            groupPurchaseStatus = 2;
                        } else if (groupPurchaseGoodsItemId != 0 && (groupPurchaseGoodsItemId.equals(nextGroupPurchaseGoodsItemId))) {
                            groupPurchaseStatus = 3;
                        }
                    }
                    MemberGroupPurchaseDO newMemberGroupPurchaseDO = new MemberGroupPurchaseDO();
                    if (newLeader != null) {
                        /**
                         * 创建新的主团
                         */
                        newMemberGroupPurchaseDO.setTeamName(newLeader.getRegisterName());
                        newMemberGroupPurchaseDO.setMaxPersonnelNumber(maxPersonnelNumber);
                        newMemberGroupPurchaseDO.setPersonnelNumber(updatePersonnelNumber);
                        newMemberGroupPurchaseDO.setNature(memberGroupPurchaseDO.getNature());
                        newMemberGroupPurchaseDO.setStatus(groupPurchaseStatus);
                        newMemberGroupPurchaseDO.setUserId(memberGroupPurchaseDO.getUserId());
                        newMemberGroupPurchaseDO.setMemberId(newLeader.getMemberId());
                        newMemberGroupPurchaseDO.setMemberWxUserId(newLeader.getMemberWxUserId());
                        newMemberGroupPurchaseDO.setActivityId(memberGroupPurchaseDO.getActivityId());
                        newMemberGroupPurchaseDO.setGroupPurchaseGoodsId(memberGroupPurchaseDO.getGroupPurchaseGoodsId());
                        newMemberGroupPurchaseDO.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                        newMemberGroupPurchaseDO.setNextGroupPurchaseGoodsItemId(nextGroupPurchaseGoodsItemId);
                        memberGroupPurchaseMapper.insert(newMemberGroupPurchaseDO);
                        for (MemberGroupPurchaseItemDO purchaseItemDO : purchaseItemDOS) {
                            purchaseItemDO.setGroupPurchaseId(newMemberGroupPurchaseDO.getId());
                        }
                        memberGroupPurchaseItemMapper.updateBatchById(purchaseItemDOS);
                    } else {
                        /**
                         * 更新旧团
                         */
                        memberGroupPurchaseDO.setStatus(groupPurchaseStatus);
                        memberGroupPurchaseDO.setMaxPersonnelNumber(maxPersonnelNumber);
                        memberGroupPurchaseDO.setPersonnelNumber(updatePersonnelNumber);
                        memberGroupPurchaseDO.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                        memberGroupPurchaseDO.setNextGroupPurchaseGoodsItemId(nextGroupPurchaseGoodsItemId);
                    }
                    memberGroupPurchaseMapper.updateById(memberGroupPurchaseDO);

                    /**
                     * 更新受影响的订单
                     */
                    if (orderDOS != null && orderDOS.size() > 0) {
                        for (OrderDO aDo : orderDOS) {
                            if (newLeader != null) {
                                aDo.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                                aDo.setGroupPurchaseId(newMemberGroupPurchaseDO.getId());
                            } else {
                                aDo.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                            }
                        }
                        orderMapper.updateBatchById(orderDOS);
                    }

                    refundTradeDO.setRefundNo(refundSn);
                    refundTradeDO.setRefundType("manual");
                    refundTradeDO.setLaunchTime(DateUtil.getDateTimeString());
                    refundTradeDO.setRefundAmount(order.getRealityPayAmount());
                    refundTradeDO.setRefundStatus("refunding");
                    refundTradeDO.setOrderNo(order.getOrderNo());
                    refundTradeDO.setRefundWay("ORIGINAL");
                    refundTradeDO.setUserId(order.getUserId());
                    refundTradeMapper.insert(refundTradeDO);
                    order.setStatus(3);
                    return orderMapper.updateById(order) > 0;
                }
                if (Status.ABNORMAL.equals(status)) {
                    throw new ServiceException("退款异常");
                }
                if (Status.CLOSED.equals(status)) {
                    throw new ServiceException("退款关闭");
                }
            } catch (Exception e) {
                logger.error("订单状态异常{}",e.getMessage());
                throw new ServiceException("订单状态异常：" + e.getMessage());
            }
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void refundNotify(HttpServletRequest request) {
        try {
            //读取请求体的信息
            ServletInputStream inputStream = request.getInputStream();
            StringBuffer stringBuffer = new StringBuffer();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String s;
            //读取回调请求体
            while ((s = bufferedReader.readLine()) != null) {
                stringBuffer.append(s);
            }
            String s1 = stringBuffer.toString();
            String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
            String nonce = request.getHeader(WECHAT_PAY_NONCE);
            String signType = request.getHeader("Wechatpay-Signature-Type");
            String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
            String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
            // 没有的话，则构造一个
            NotificationConfig config = new RSAAutoCertificateConfig.Builder()
                .merchantId(yjjExternalAuthConfig.getMchid())
                .privateKeyFromPath(yjjExternalAuthConfig.getKeyPath())
                .merchantSerialNumber(yjjExternalAuthConfig.getMchSerialNo())
                .apiV3Key(yjjExternalAuthConfig.getKey())
                .build();
            // 初始化 NotificationParser
            NotificationParser parser = new NotificationParser(config);
            RequestParam requestParam = new RequestParam.Builder()
                .serialNumber(serialNo)
                .nonce(nonce)
                .signature(signature)
                .timestamp(timestamp)
                // 若未设置signType，默认值为 WECHATPAY2-SHA256-RSA2048
                .signType(signType)
                .body(s1)
                .build();
            RefundNotification parse = parser.parse(requestParam, RefundNotification.class);
            logger.info("退款返回参数 parse" + parse);
            Status refundStatus = parse.getRefundStatus();
            if (Status.SUCCESS.equals(refundStatus)) {

                /**
                 * 更新订单状态
                 */
                LambdaQueryWrapper<OrderDO> orderWrapper = Wrappers.lambdaQuery(OrderDO.class);
                orderWrapper.eq(OrderDO::getOrderNo,parse.getOutTradeNo());
                OrderDO orderDO = orderMapper.selectOne(orderWrapper);
                if (orderDO == null) {
                    throw new SecurityException("没有查询到需要退款的订单");
                }

                /**
                 * 更新退款状态
                 */
                LambdaQueryWrapper<RefundTradeDO> refundWrapper = Wrappers.lambdaQuery(RefundTradeDO.class);
                refundWrapper.eq(RefundTradeDO::getRefundNo,parse.getOutRefundNo())
                    .eq(RefundTradeDO::getOrderNo,parse.getOutTradeNo());
                RefundTradeDO refundTradeDO = refundTradeMapper.selectOne(refundWrapper);
                if (refundTradeDO == null) {
                    throw new SecurityException("退款账单不存在");
                }
                refundTradeDO.setRefundStatus("success");
                refundTradeDO.setThirdTradeNo(parse.getTransactionId());
                refundTradeDO.setRefundTime(DateUtil.getDateTimeString());
                refundTradeMapper.updateById(refundTradeDO);

                /**
                 * 更新分享者数据
                 */
                ShareDO shareDO = shareMapper.selectById(orderDO.getShareId());
                if (shareDO != null) {
                    shareDO.setMemberBuyNumber(shareDO.getMemberBuyNumber() - 1);
                    shareDO.setBuyNumber(shareDO.getBuyNumber() - 1);
                    shareDO.setPayTotal(shareDO.getPayTotal().subtract(refundTradeDO.getRefundAmount()));
                    shareMapper.updateById(shareDO);
                }

                /**
                 * 更新用户数据
                 */
                MemberDO memberDO = memberMapper.selectById(orderDO.getMemberId());
                if (memberDO != null) {
                    if (memberDO.getTransactionTotalAmount() != null) {
                        memberDO.setTransactionTotalAmount(memberDO.getTransactionTotalAmount().subtract(refundTradeDO.getRefundAmount()));
                    }
                    memberDO.setTransactionNumber(memberDO.getTransactionNumber() - 1);
                    memberMapper.updateById(memberDO);
                }

                /**
                 * 更新用户自己的分享数据
                 */
                LambdaQueryWrapper<ShareDO> shareWrapper = Wrappers.lambdaQuery(ShareDO.class);
                shareWrapper.eq(ShareDO::getMemberId,orderDO.getMemberId())
                    .eq(ShareDO::getProductId,orderDO.getActivityId());
                ShareDO memberShareDO = shareMapper.selectOne(shareWrapper);
                if (memberShareDO != null) {
                    memberShareDO.setEnrollStatus(2);
                    shareMapper.updateById(memberShareDO);
                }

                /**
                 * 更新订单信息
                 */
                orderDO.setStatus(4);
                orderDO.setCloseReason("手动退款");
                orderDO.setSettlementStatus(2);
                orderMapper.updateById(orderDO);

                /**
                 * 更新资金记录
                 */
                List<OrderTradeRecordDO> tradeRecordList = new ArrayList<>();
                // 退款
                OrderTradeRecordDO refundTradeRecordDO = new OrderTradeRecordDO();
                refundTradeRecordDO.setOrderId(orderDO.getId());
                refundTradeRecordDO.setFundType("refund");
                refundTradeRecordDO.setTradeAmount(orderDO.getRealityPayAmount().negate());
                refundTradeRecordDO.setMemberId(orderDO.getMemberId());
                refundTradeRecordDO.setMemberWxUserId(orderDO.getMemberWxUserId());
                refundTradeRecordDO.setSettlementStatus(2);
                refundTradeRecordDO.setUserId(orderDO.getUserId());
                tradeRecordList.add(refundTradeRecordDO);
                // 手续费返还
                OrderTradeRecordDO returnFeeTradeRecordDO = new OrderTradeRecordDO();
                returnFeeTradeRecordDO.setOrderId(orderDO.getId());
                returnFeeTradeRecordDO.setFundType("return_fee");
                returnFeeTradeRecordDO.setTradeAmount(orderDO.getCommission());
                returnFeeTradeRecordDO.setMemberId(orderDO.getMemberId());
                returnFeeTradeRecordDO.setMemberWxUserId(orderDO.getMemberWxUserId());
                returnFeeTradeRecordDO.setSettlementStatus(2);
                returnFeeTradeRecordDO.setUserId(orderDO.getUserId());
                tradeRecordList.add(returnFeeTradeRecordDO);
                orderTradeRecordMapper.insertBatch(tradeRecordList);
            }
            if (Status.PROCESSING.equals(refundStatus)) {
                throw new ServiceException("退款中");
            }
            if (Status.ABNORMAL.equals(refundStatus)) {
                throw new ServiceException("退款异常");
            }
            if (Status.CLOSED.equals(refundStatus)) {
                throw new ServiceException("退款关闭");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServiceException(e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchRefund(Long[] ids) {
        List<Long> orderIds = Arrays.asList(ids);
        for (Long orderId : orderIds) {
            synchronized (this) {
                /**
                 * 获取订单信息
                 */
                OrderDO order = orderMapper.selectById(orderId);
                if (order == null) {
                    throw new ServiceException("无订单信息");
                }
                /**
                 * 获取订单支付信息
                 */
                LambdaQueryWrapper<PaymentBillDO> paymentBillWrapper = Wrappers.lambdaQuery(PaymentBillDO.class);
                paymentBillWrapper.eq(PaymentBillDO::getOrderNo,order.getOrderNo()).eq(PaymentBillDO::getIsPay,1);
                PaymentBillVO paymentBillVO = paymentBillMapper.selectVoOne(paymentBillWrapper);
                String refundSn = SnCreator.getRefundSn();
                RefundTradeDO refundTradeDO = new RefundTradeDO();
                if (paymentBillVO == null) {
                    throw new ServiceException("没有查询到订单支付信息");
                }

                /**
                 * 查询金额是否足够
                 */
                SysUser sysUser = sysUserMapper.selectVoById(order.getUserId());
                if (sysUser == null) {
                    throw new ServiceException("未查询到商家信息");
                }
                //待核销状态只需要关注是否产生分销金额
                if (order.getStatus() == 2) {
                    BigDecimal distributionAmount = order.getOneDistributionAmount().add(order.getTwoDistributionAmount());
                    BigDecimal waitSettlementAmount = Convert.toBigDecimal(sysUser.getWaitSettlementAmount(),BigDecimal.ZERO);
                    BigDecimal walletAmount = Convert.toBigDecimal(sysUser.getWalletAmount(),BigDecimal.ZERO);
                    //订单待核销钱还未分账（只需要关注钱够不够结算分销金额即可）
                    if (distributionAmount.compareTo(BigDecimal.ZERO) == 1) {
                        //表示该订单产生分销金额
                        if (waitSettlementAmount.compareTo(distributionAmount) == -1) {
                            //表示待清算金额小于分销总金额
                            if (walletAmount.compareTo(distributionAmount) == -1) {
                                //表示可提现金额小于分销总金额
                                if (waitSettlementAmount.add(walletAmount).compareTo(distributionAmount) == -1) {
                                    //表示 待清算金额 + 可提现金额小于分销总金额
                                    throw new ServiceException("余额不足，请充值后再进行退款");
                                } else {
                                    //先扣除待请算金额的钱，差的从可提现金额里面扣
                                    sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                                    BigDecimal difference = distributionAmount.subtract(waitSettlementAmount);
                                    sysUser.setWalletAmount(walletAmount.subtract(difference));
                                }
                            } else {
                                //先扣除待请算金额的钱，差的从可提现金额里面扣
                                sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                                BigDecimal difference = distributionAmount.subtract(waitSettlementAmount);
                                sysUser.setWalletAmount(walletAmount.subtract(difference));
                            }
                        } else {
                            //超出的金额从待清算金额里面扣
                            sysUser.setWaitSettlementAmount(waitSettlementAmount.subtract(distributionAmount));
                        }
                    }
                } else {
                    //订单已核销（已结算至待清算金额）
                    BigDecimal settlementAmountAmount = order.getOneDistributionAmount().add(order.getTwoDistributionAmount()).add(order.getActualAmount());
                    BigDecimal waitSettlementAmount = Convert.toBigDecimal(sysUser.getWaitSettlementAmount(),BigDecimal.ZERO);
                    BigDecimal walletAmount = Convert.toBigDecimal(sysUser.getWalletAmount(),BigDecimal.ZERO);
                    //订单待核销钱还未分账（只需要关注钱够不够结算分销金额即可）
                    if (settlementAmountAmount.compareTo(BigDecimal.ZERO) == 1) {
                        if (waitSettlementAmount.compareTo(settlementAmountAmount) == -1) {
                            if (walletAmount.compareTo(settlementAmountAmount) == -1) {
                                if (waitSettlementAmount.add(walletAmount).compareTo(settlementAmountAmount) == -1) {
                                    //表示 待清算金额 + 可提现金额小于分销总金额
                                    throw new ServiceException("余额不足，请充值后再进行退款");
                                } else {
                                    //先扣除待请算金额的钱，差的从可提现金额里面扣
                                    sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                                    BigDecimal difference = settlementAmountAmount.subtract(waitSettlementAmount);
                                    sysUser.setWalletAmount(walletAmount.subtract(difference));
                                }
                            } else {
                                //先扣除待请算金额的钱，差的从可提现金额里面扣
                                sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                                BigDecimal difference = settlementAmountAmount.subtract(waitSettlementAmount);
                                sysUser.setWalletAmount(walletAmount.subtract(difference));
                            }
                        } else {
                            //超出的金额从待清算金额里面扣
                            sysUser.setWaitSettlementAmount(waitSettlementAmount.subtract(settlementAmountAmount));
                        }
                    }
                }
                try {
                    // 使用自动更新平台证书的RSA配置
                    // 一个商户号只能初始化一个配置，否则会因为重复的下载任务报错
                    Config config =
                        new RSAAutoCertificateConfig.Builder()
                            .merchantId(yjjExternalAuthConfig.getMchid())
                            //使用 SDK 不需要计算请求签名和验证应答签名
                            // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
                            .privateKeyFromPath(yjjExternalAuthConfig.getKeyPath())
                            .merchantSerialNumber(yjjExternalAuthConfig.getMchSerialNo())
                            .apiV3Key(yjjExternalAuthConfig.getKey())
                            .build();
                    // 构建退款service
                    RefundService service = new RefundService.Builder().config(config).build();
                    //构建退款请求
                    CreateRequest request = new CreateRequest();
                    //构建订单金额信息
                    AmountReq amountReq = new AmountReq();
                    //退款金额
                    Integer getRealityPayAmount = Convert.toInt(order.getRealityPayAmount().multiply(Convert.toBigDecimal(100)));
//                测试使用
//                Integer getRealityPayAmount = 1;
                    amountReq.setRefund(Convert.toLong(getRealityPayAmount));
                    //原订单金额
                    amountReq.setTotal(Convert.toLong(getRealityPayAmount));
                    //货币类型(默认人民币)
                    amountReq.setCurrency("CNY");
                    request.setAmount(amountReq);
                    request.setOutTradeNo(paymentBillVO.getOrderNo());
                    request.setReason("退款");
                    //商户退款单号
                    request.setOutRefundNo(refundSn);
                    request.setNotifyUrl(yjjExternalAuthConfig.getRefundNotifyUrl());
                    // 调用微信sdk退款接口
                    Refund refund = service.create(request);
                    //接收退款返回参数
                    Status status = refund.getStatus();
                    logger.info("请求退款返回status：" + status);
                    if (Status.SUCCESS.equals(status)) {
                        logger.info("退款成功 ---> status：" + status);
                        continue;
                    }
                    if (Status.PROCESSING.equals(status)) {
                        logger.info("退款中 ---> status：" + status);

                        /**
                         * 更新商家信息
                         */
                        sysUserMapper.updateById(sysUser);

                        /**
                         * 更新拼团表数据
                         */
                        MemberGroupPurchaseItemDO newLeader = null;
                        MemberGroupPurchaseItemDO memberGroupPurchaseItemDO = memberGroupPurchaseItemMapper.selectById(order.getGroupPurchaseItemId());
                        if (memberGroupPurchaseItemDO == null) {
                            throw new ServiceException("拼团不存在");
                        }
                        MemberGroupPurchaseDO memberGroupPurchaseDO = memberGroupPurchaseMapper.selectById(order.getGroupPurchaseId());
                        if (memberGroupPurchaseDO == null) {
                            throw new ServiceException("拼团不存在");
                        }
                        /**
                         * 查看具有相同拼团id的订单
                         */
                        List<OrderDO> orderDOS = orderMapper.selectList(
                            new LambdaQueryWrapper<OrderDO>()
                                .eq(OrderDO::getGroupPurchaseId,memberGroupPurchaseDO.getId()).in(OrderDO::getStatus,1,2,5));

                        /**
                         * 作废当前子拼团信息
                         */
                        memberGroupPurchaseItemDO.setIsNullify(1);
                        memberGroupPurchaseItemMapper.updateById(memberGroupPurchaseItemDO);
                        /**
                         * 如果退款的是团长，选这一个新的团长
                         */
                        LambdaQueryWrapper<MemberGroupPurchaseItemDO> wrapper = Wrappers.lambdaQuery(MemberGroupPurchaseItemDO.class);
                        wrapper.eq(MemberGroupPurchaseItemDO::getGroupPurchaseId,order.getGroupPurchaseId())
                            .eq(MemberGroupPurchaseItemDO::getIsNullify,0)
                            .ne(MemberGroupPurchaseItemDO::getId,memberGroupPurchaseItemDO.getId())
                            .orderByAsc(MemberGroupPurchaseItemDO::getCreateTime);
                        List<MemberGroupPurchaseItemDO> purchaseItemDOS = memberGroupPurchaseItemMapper.selectList(wrapper);
                        if (memberGroupPurchaseItemDO.getIdentity() == 1) {
                            if (purchaseItemDOS != null && purchaseItemDOS.size() > 0) {
                                newLeader = purchaseItemDOS.get(0);
                                newLeader.setIdentity(1);
                                memberGroupPurchaseItemMapper.updateById(newLeader);
                            }
                            /**
                             * 作废该主团
                             */
                            memberGroupPurchaseDO.setStatus(-1);
                        }

                        /**
                         * 更新拼团主表数据
                         */
                        Integer updatePersonnelNumber = memberGroupPurchaseDO.getPersonnelNumber() - 1;

                        //更新当前拼团信息
                        LambdaQueryWrapper<GroupPurchaseGoodsItemDO> groupPurchaseGoodsItemWrapper = Wrappers.lambdaQuery(GroupPurchaseGoodsItemDO.class);
                        groupPurchaseGoodsItemWrapper.eq(GroupPurchaseGoodsItemDO::getGroupPurchaseGoodsId,order.getGroupPurchaseGoodsId())
                            .orderByAsc(GroupPurchaseGoodsItemDO::getConstituteNumber);
                        List<GroupPurchaseGoodsItemDO> goodsItemDOS = groupPurchaseGoodsItemMapper.selectList(groupPurchaseGoodsItemWrapper);
                        //当前拼团商品阶梯id
                        Long groupPurchaseGoodsItemId = 0L;
                        Integer maxPersonnelNumber = 0;
                        //当前拼团下一个商品阶梯id
                        Long nextGroupPurchaseGoodsItemId = 0L;
                        Integer groupPurchaseStatus = -1;
                        if (updatePersonnelNumber > 0) {
                            if (goodsItemDOS != null && goodsItemDOS.size() > 0) {
                                for (GroupPurchaseGoodsItemDO goodsItemDO : goodsItemDOS) {
                                    if (updatePersonnelNumber >= goodsItemDO.getConstituteNumber()) {
                                        groupPurchaseGoodsItemId = goodsItemDO.getId();
                                        maxPersonnelNumber = goodsItemDO.getConstituteNumber();
                                        nextGroupPurchaseGoodsItemId = goodsItemDO.getId();
                                    } else {
                                        nextGroupPurchaseGoodsItemId = goodsItemDO.getId();
                                        break;
                                    }
                                }
                            }
                            if (groupPurchaseGoodsItemId == 0) {
                                groupPurchaseStatus = 1;
                            } else if (groupPurchaseGoodsItemId != 0 && (!groupPurchaseGoodsItemId.equals(nextGroupPurchaseGoodsItemId))) {
                                groupPurchaseStatus = 2;
                            } else if (groupPurchaseGoodsItemId != 0 && (groupPurchaseGoodsItemId.equals(nextGroupPurchaseGoodsItemId))) {
                                groupPurchaseStatus = 3;
                            }
                        }
                        MemberGroupPurchaseDO newMemberGroupPurchaseDO = new MemberGroupPurchaseDO();
                        if (newLeader != null) {
                            /**
                             * 创建新的主团
                             */
                            newMemberGroupPurchaseDO.setTeamName(newLeader.getRegisterName());
                            newMemberGroupPurchaseDO.setMaxPersonnelNumber(maxPersonnelNumber);
                            newMemberGroupPurchaseDO.setPersonnelNumber(updatePersonnelNumber);
                            newMemberGroupPurchaseDO.setNature(memberGroupPurchaseDO.getNature());
                            newMemberGroupPurchaseDO.setStatus(groupPurchaseStatus);
                            newMemberGroupPurchaseDO.setUserId(memberGroupPurchaseDO.getUserId());
                            newMemberGroupPurchaseDO.setMemberId(newLeader.getMemberId());
                            newMemberGroupPurchaseDO.setMemberWxUserId(newLeader.getMemberWxUserId());
                            newMemberGroupPurchaseDO.setActivityId(memberGroupPurchaseDO.getActivityId());
                            newMemberGroupPurchaseDO.setGroupPurchaseGoodsId(memberGroupPurchaseDO.getGroupPurchaseGoodsId());
                            newMemberGroupPurchaseDO.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                            newMemberGroupPurchaseDO.setNextGroupPurchaseGoodsItemId(nextGroupPurchaseGoodsItemId);
                            memberGroupPurchaseMapper.insert(newMemberGroupPurchaseDO);
                            for (MemberGroupPurchaseItemDO purchaseItemDO : purchaseItemDOS) {
                                purchaseItemDO.setGroupPurchaseId(newMemberGroupPurchaseDO.getId());
                            }
                            memberGroupPurchaseItemMapper.updateBatchById(purchaseItemDOS);
                        } else {
                            /**
                             * 更新旧团
                             */
                            memberGroupPurchaseDO.setStatus(groupPurchaseStatus);
                            memberGroupPurchaseDO.setMaxPersonnelNumber(maxPersonnelNumber);
                            memberGroupPurchaseDO.setPersonnelNumber(updatePersonnelNumber);
                            memberGroupPurchaseDO.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                            memberGroupPurchaseDO.setNextGroupPurchaseGoodsItemId(nextGroupPurchaseGoodsItemId);
                        }
                        memberGroupPurchaseMapper.updateById(memberGroupPurchaseDO);

                        /**
                         * 更新受影响的订单
                         */
                        if (orderDOS != null && orderDOS.size() > 0) {
                            for (OrderDO aDo : orderDOS) {
                                if (newLeader != null) {
                                    aDo.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                                    aDo.setGroupPurchaseId(newMemberGroupPurchaseDO.getId());
                                } else {
                                    aDo.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                                }
                            }
                            orderMapper.updateBatchById(orderDOS);
                        }

                        refundTradeDO.setRefundNo(refundSn);
                        refundTradeDO.setRefundType("manual");
                        refundTradeDO.setLaunchTime(DateUtil.getDateTimeString());
                        refundTradeDO.setRefundAmount(order.getRealityPayAmount());
                        refundTradeDO.setRefundStatus("refunding");
                        refundTradeDO.setOrderNo(order.getOrderNo());
                        refundTradeDO.setRefundWay("ORIGINAL");
                        refundTradeDO.setUserId(order.getUserId());
                        refundTradeMapper.insert(refundTradeDO);
                        order.setStatus(3);
                        orderMapper.updateById(order);
                    }
                    if (Status.ABNORMAL.equals(status)) {
                        throw new ServiceException("退款异常");
                    }
                    if (Status.CLOSED.equals(status)) {
                        throw new ServiceException("退款关闭");
                    }
                } catch (Exception e) {
                    logger.error("订单状态异常{}",e.getMessage());
                    throw new ServiceException("订单状态异常：" + e.getMessage());
                }
            }
        }
        return true;
    }

    /**
     * 定时退款
     */
    @Scheduled(cron = "0/10 * * * * ?")
    public void handleRefund() {
        /**
         * 获取订单信息
         */
        OrderDO order = orderMapper.selectOne(new LambdaQueryWrapper<OrderDO>()
            .in(OrderDO::getStatus,2,5)
            .eq(OrderDO::getActivityId,1963547482448142338L)
            .orderByAsc(OrderDO::getCreateTime)
            .last("limit 1"));
        if (order == null) {
            throw new ServiceException("无订单信息");
        }
        /**
         * 获取订单支付信息
         */
        LambdaQueryWrapper<PaymentBillDO> paymentBillWrapper = Wrappers.lambdaQuery(PaymentBillDO.class);
        paymentBillWrapper.eq(PaymentBillDO::getOrderNo,order.getOrderNo()).eq(PaymentBillDO::getIsPay,1);
        PaymentBillVO paymentBillVO = paymentBillMapper.selectVoOne(paymentBillWrapper);
        String refundSn = SnCreator.getRefundSn();
        RefundTradeDO refundTradeDO = new RefundTradeDO();
        if (paymentBillVO == null) {
            throw new ServiceException("没有查询到订单支付信息");
        }

        /**
         * 查询金额是否足够
         */
        SysUser sysUser = sysUserMapper.selectVoById(order.getUserId());
        if (sysUser == null) {
            throw new ServiceException("未查询到商家信息");
        }
        //待核销状态只需要关注是否产生分销金额
        if (order.getStatus() == 2) {
            BigDecimal distributionAmount = order.getOneDistributionAmount().add(order.getTwoDistributionAmount());
            BigDecimal waitSettlementAmount = Convert.toBigDecimal(sysUser.getWaitSettlementAmount(),BigDecimal.ZERO);
            BigDecimal walletAmount = Convert.toBigDecimal(sysUser.getWalletAmount(),BigDecimal.ZERO);
            //订单待核销钱还未分账（只需要关注钱够不够结算分销金额即可）
            if (distributionAmount.compareTo(BigDecimal.ZERO) == 1) {
                //表示该订单产生分销金额
                if (waitSettlementAmount.compareTo(distributionAmount) == -1) {
                    //表示待清算金额小于分销总金额
                    if (walletAmount.compareTo(distributionAmount) == -1) {
                        //表示可提现金额小于分销总金额
                        if (waitSettlementAmount.add(walletAmount).compareTo(distributionAmount) == -1) {
                            //表示 待清算金额 + 可提现金额小于分销总金额
                            throw new ServiceException("余额不足，请充值后再进行退款");
                        } else {
                            //先扣除待请算金额的钱，差的从可提现金额里面扣
                            sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                            BigDecimal difference = distributionAmount.subtract(waitSettlementAmount);
                            sysUser.setWalletAmount(walletAmount.subtract(difference));
                        }
                    } else {
                        //先扣除待请算金额的钱，差的从可提现金额里面扣
                        sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                        BigDecimal difference = distributionAmount.subtract(waitSettlementAmount);
                        sysUser.setWalletAmount(walletAmount.subtract(difference));
                    }
                } else {
                    //超出的金额从待清算金额里面扣
                    sysUser.setWaitSettlementAmount(waitSettlementAmount.subtract(distributionAmount));
                }
            }
        } else {
            //订单已核销（已结算至待清算金额）
            BigDecimal settlementAmountAmount = order.getOneDistributionAmount().add(order.getTwoDistributionAmount()).add(order.getActualAmount());
            BigDecimal waitSettlementAmount = Convert.toBigDecimal(sysUser.getWaitSettlementAmount(),BigDecimal.ZERO);
            BigDecimal walletAmount = Convert.toBigDecimal(sysUser.getWalletAmount(),BigDecimal.ZERO);
            //订单待核销钱还未分账（只需要关注钱够不够结算分销金额即可）
            if (settlementAmountAmount.compareTo(BigDecimal.ZERO) == 1) {
                if (waitSettlementAmount.compareTo(settlementAmountAmount) == -1) {
                    if (walletAmount.compareTo(settlementAmountAmount) == -1) {
                        if (waitSettlementAmount.add(walletAmount).compareTo(settlementAmountAmount) == -1) {
                            //表示 待清算金额 + 可提现金额小于分销总金额
                            throw new ServiceException("余额不足，请充值后再进行退款");
                        } else {
                            //先扣除待请算金额的钱，差的从可提现金额里面扣
                            sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                            BigDecimal difference = settlementAmountAmount.subtract(waitSettlementAmount);
                            sysUser.setWalletAmount(walletAmount.subtract(difference));
                        }
                    } else {
                        //先扣除待请算金额的钱，差的从可提现金额里面扣
                        sysUser.setWaitSettlementAmount(BigDecimal.ZERO);
                        BigDecimal difference = settlementAmountAmount.subtract(waitSettlementAmount);
                        sysUser.setWalletAmount(walletAmount.subtract(difference));
                    }
                } else {
                    //超出的金额从待清算金额里面扣
                    sysUser.setWaitSettlementAmount(waitSettlementAmount.subtract(settlementAmountAmount));
                }
            }
        }
        try {
            // 使用自动更新平台证书的RSA配置
            // 一个商户号只能初始化一个配置，否则会因为重复的下载任务报错
            Config config =
                new RSAAutoCertificateConfig.Builder()
                    .merchantId(yjjExternalAuthConfig.getMchid())
                    //使用 SDK 不需要计算请求签名和验证应答签名
                    // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥，商户私钥会用来生成请求的签名
                    .privateKeyFromPath(yjjExternalAuthConfig.getKeyPath())
                    .merchantSerialNumber(yjjExternalAuthConfig.getMchSerialNo())
                    .apiV3Key(yjjExternalAuthConfig.getKey())
                    .build();
            // 构建退款service
            RefundService service = new RefundService.Builder().config(config).build();
            //构建退款请求
            CreateRequest request = new CreateRequest();
            //构建订单金额信息
            AmountReq amountReq = new AmountReq();
            //退款金额
            Integer getRealityPayAmount = Convert.toInt(order.getRealityPayAmount().multiply(Convert.toBigDecimal(100)));
//                测试使用
//                Integer getRealityPayAmount = 1;
            amountReq.setRefund(Convert.toLong(getRealityPayAmount));
            //原订单金额
            amountReq.setTotal(Convert.toLong(getRealityPayAmount));
            //货币类型(默认人民币)
            amountReq.setCurrency("CNY");
            request.setAmount(amountReq);
            request.setOutTradeNo(paymentBillVO.getOrderNo());
            request.setReason("退款");
            //商户退款单号
            request.setOutRefundNo(refundSn);
            request.setNotifyUrl(yjjExternalAuthConfig.getRefundNotifyUrl());
            // 调用微信sdk退款接口
            Refund refund = service.create(request);
            //接收退款返回参数
            Status status = refund.getStatus();
            logger.info("请求退款返回status：" + status);
            if (Status.SUCCESS.equals(status)) {
                logger.info("退款成功 ---> status：" + status);
            }
            if (Status.PROCESSING.equals(status)) {
                logger.info("退款中 ---> status：" + status);

                /**
                 * 更新商家信息
                 */
                sysUserMapper.updateById(sysUser);

                /**
                 * 更新拼团表数据
                 */
                MemberGroupPurchaseItemDO newLeader = null;
                MemberGroupPurchaseItemDO memberGroupPurchaseItemDO = memberGroupPurchaseItemMapper.selectById(order.getGroupPurchaseItemId());
                if (memberGroupPurchaseItemDO == null) {
                    throw new ServiceException("拼团不存在");
                }
                MemberGroupPurchaseDO memberGroupPurchaseDO = memberGroupPurchaseMapper.selectById(order.getGroupPurchaseId());
                if (memberGroupPurchaseDO == null) {
                    throw new ServiceException("拼团不存在");
                }
                /**
                 * 查看具有相同拼团id的订单
                 */
                List<OrderDO> orderDOS = orderMapper.selectList(
                    new LambdaQueryWrapper<OrderDO>()
                        .eq(OrderDO::getGroupPurchaseId,memberGroupPurchaseDO.getId()).in(OrderDO::getStatus,1,2,5));

                /**
                 * 作废当前子拼团信息
                 */
                memberGroupPurchaseItemDO.setIsNullify(1);
                memberGroupPurchaseItemMapper.updateById(memberGroupPurchaseItemDO);
                /**
                 * 如果退款的是团长，选这一个新的团长
                 */
                LambdaQueryWrapper<MemberGroupPurchaseItemDO> wrapper = Wrappers.lambdaQuery(MemberGroupPurchaseItemDO.class);
                wrapper.eq(MemberGroupPurchaseItemDO::getGroupPurchaseId,order.getGroupPurchaseId())
                    .eq(MemberGroupPurchaseItemDO::getIsNullify,0)
                    .ne(MemberGroupPurchaseItemDO::getId,memberGroupPurchaseItemDO.getId())
                    .orderByAsc(MemberGroupPurchaseItemDO::getCreateTime);
                List<MemberGroupPurchaseItemDO> purchaseItemDOS = memberGroupPurchaseItemMapper.selectList(wrapper);
                if (memberGroupPurchaseItemDO.getIdentity() == 1) {
                    if (purchaseItemDOS != null && purchaseItemDOS.size() > 0) {
                        newLeader = purchaseItemDOS.get(0);
                        newLeader.setIdentity(1);
                        memberGroupPurchaseItemMapper.updateById(newLeader);
                    }
                    /**
                     * 作废该主团
                     */
                    memberGroupPurchaseDO.setStatus(-1);
                }

                /**
                 * 更新拼团主表数据
                 */
                Integer updatePersonnelNumber = memberGroupPurchaseDO.getPersonnelNumber() - 1;

                //更新当前拼团信息
                LambdaQueryWrapper<GroupPurchaseGoodsItemDO> groupPurchaseGoodsItemWrapper = Wrappers.lambdaQuery(GroupPurchaseGoodsItemDO.class);
                groupPurchaseGoodsItemWrapper.eq(GroupPurchaseGoodsItemDO::getGroupPurchaseGoodsId,order.getGroupPurchaseGoodsId())
                    .orderByAsc(GroupPurchaseGoodsItemDO::getConstituteNumber);
                List<GroupPurchaseGoodsItemDO> goodsItemDOS = groupPurchaseGoodsItemMapper.selectList(groupPurchaseGoodsItemWrapper);
                //当前拼团商品阶梯id
                Long groupPurchaseGoodsItemId = 0L;
                Integer maxPersonnelNumber = 0;
                //当前拼团下一个商品阶梯id
                Long nextGroupPurchaseGoodsItemId = 0L;
                Integer groupPurchaseStatus = -1;
                if (updatePersonnelNumber > 0) {
                    if (goodsItemDOS != null && goodsItemDOS.size() > 0) {
                        for (GroupPurchaseGoodsItemDO goodsItemDO : goodsItemDOS) {
                            if (updatePersonnelNumber >= goodsItemDO.getConstituteNumber()) {
                                groupPurchaseGoodsItemId = goodsItemDO.getId();
                                maxPersonnelNumber = goodsItemDO.getConstituteNumber();
                                nextGroupPurchaseGoodsItemId = goodsItemDO.getId();
                            } else {
                                nextGroupPurchaseGoodsItemId = goodsItemDO.getId();
                                break;
                            }
                        }
                    }
                    if (groupPurchaseGoodsItemId == 0) {
                        groupPurchaseStatus = 1;
                    } else if (groupPurchaseGoodsItemId != 0 && (!groupPurchaseGoodsItemId.equals(nextGroupPurchaseGoodsItemId))) {
                        groupPurchaseStatus = 2;
                    } else if (groupPurchaseGoodsItemId != 0 && (groupPurchaseGoodsItemId.equals(nextGroupPurchaseGoodsItemId))) {
                        groupPurchaseStatus = 3;
                    }
                }
                MemberGroupPurchaseDO newMemberGroupPurchaseDO = new MemberGroupPurchaseDO();
                if (newLeader != null) {
                    /**
                     * 创建新的主团
                     */
                    newMemberGroupPurchaseDO.setTeamName(newLeader.getRegisterName());
                    newMemberGroupPurchaseDO.setMaxPersonnelNumber(maxPersonnelNumber);
                    newMemberGroupPurchaseDO.setPersonnelNumber(updatePersonnelNumber);
                    newMemberGroupPurchaseDO.setNature(memberGroupPurchaseDO.getNature());
                    newMemberGroupPurchaseDO.setStatus(groupPurchaseStatus);
                    newMemberGroupPurchaseDO.setUserId(memberGroupPurchaseDO.getUserId());
                    newMemberGroupPurchaseDO.setMemberId(newLeader.getMemberId());
                    newMemberGroupPurchaseDO.setMemberWxUserId(newLeader.getMemberWxUserId());
                    newMemberGroupPurchaseDO.setActivityId(memberGroupPurchaseDO.getActivityId());
                    newMemberGroupPurchaseDO.setGroupPurchaseGoodsId(memberGroupPurchaseDO.getGroupPurchaseGoodsId());
                    newMemberGroupPurchaseDO.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                    newMemberGroupPurchaseDO.setNextGroupPurchaseGoodsItemId(nextGroupPurchaseGoodsItemId);
                    memberGroupPurchaseMapper.insert(newMemberGroupPurchaseDO);
                    for (MemberGroupPurchaseItemDO purchaseItemDO : purchaseItemDOS) {
                        purchaseItemDO.setGroupPurchaseId(newMemberGroupPurchaseDO.getId());
                    }
                    memberGroupPurchaseItemMapper.updateBatchById(purchaseItemDOS);
                } else {
                    /**
                     * 更新旧团
                     */
                    memberGroupPurchaseDO.setStatus(groupPurchaseStatus);
                    memberGroupPurchaseDO.setMaxPersonnelNumber(maxPersonnelNumber);
                    memberGroupPurchaseDO.setPersonnelNumber(updatePersonnelNumber);
                    memberGroupPurchaseDO.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                    memberGroupPurchaseDO.setNextGroupPurchaseGoodsItemId(nextGroupPurchaseGoodsItemId);
                }
                memberGroupPurchaseMapper.updateById(memberGroupPurchaseDO);

                /**
                 * 更新受影响的订单
                 */
                if (orderDOS != null && orderDOS.size() > 0) {
                    for (OrderDO aDo : orderDOS) {
                        if (newLeader != null) {
                            aDo.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                            aDo.setGroupPurchaseId(newMemberGroupPurchaseDO.getId());
                        } else {
                            aDo.setGroupPurchaseGoodsItemId(groupPurchaseGoodsItemId);
                        }
                    }
                    orderMapper.updateBatchById(orderDOS);
                }

                refundTradeDO.setRefundNo(refundSn);
                refundTradeDO.setRefundType("manual");
                refundTradeDO.setLaunchTime(DateUtil.getDateTimeString());
                refundTradeDO.setRefundAmount(order.getRealityPayAmount());
                refundTradeDO.setRefundStatus("refunding");
                refundTradeDO.setOrderNo(order.getOrderNo());
                refundTradeDO.setRefundWay("ORIGINAL");
                refundTradeDO.setUserId(order.getUserId());
                refundTradeMapper.insert(refundTradeDO);
                order.setStatus(3);
                orderMapper.updateById(order);
            }
            if (Status.ABNORMAL.equals(status)) {
                throw new ServiceException("退款异常");
            }
            if (Status.CLOSED.equals(status)) {
                throw new ServiceException("退款关闭");
            }
        } catch (Exception e) {
            logger.error("订单状态异常{}",e.getMessage());
            throw new ServiceException("订单状态异常：" + e.getMessage());
        }
    }
}
